﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web;
using System.Reflection;
using FastReflectionLib;
using Summer.Exception;
using Summer.Web.Support;
using Summer.Core.Ioc;

#region License
/*
 *  Copyright (c) Dumuzi.cn 2009 , All rights reserved.
 *  CLR Version: 2.0.50727.4927
 *  NameSpace: Summer.Web.Mvc
 *  Author:Edwin Tai,戴佳顺
 *  Msn:edwin19861218@hotmail.com
 *  QQ: 1961218
 *  Date:2009-11-19 15:55:08
 *  Licensed under the Microsoft Public License (Ms-PL)
 *  This license governs use of the accompanying software. 
 *  If you use the software, you accept this license.
 *  If you do not accept the license, do not use the software.
 */
#endregion

namespace Summer.Web.Mvc
{
    public class MvcHandler : AbstractMvcHandler
    {
        public MvcHandler(RequestContext requestContext)
            : base(requestContext)
        {

        }
        /// <summary>
        /// Create new instance of control and execute it
        /// Before that,set all contextObject about it 
        /// </summary>
        /// <param name="httpContext"></param>
        protected override void ProcessRequest(HttpContextBase httpContext)
        {
            AddVersionHeader(httpContext);
            // Get the controller type
            string controllerName = RequestContext.RouteData.GetRequiredString("controller");
            IControllerFactory factory = ControllerBuilder.GetControllerFactory();
            IController controller = null;
            Summer.Core.Ioc.Context configContext = httpContext.ApplicationInstance.Application.GetConfigContextContainer();
            IContextObject contextObject = null;

            Func<object> setInstanceProperty = delegate
            {
                if (controller != null && contextObject.Property != null && contextObject.Property.Count() != 0)
                {
                    ContextManager.SetPropertyInContextObject(contextObject, httpContext.ApplicationInstance.Application.GetDefaultContextContainer(), controller);
                }
                return controller;
            };

            if (!configContext.TryGetValue(controllerName, out contextObject))
            {
                //The contextObject cannot be found in context
                //So the controller should be created everytime
                this.CreateNewInstance(factory, controllerName, out controller);
            }
            else
            {
                this.CreateNewInstance(factory, controllerName, out controller);
                setInstanceProperty();
                /*
                //FIXME the instance getter error
                //The Application Object in Context which in Page is null
                //How to set it?
                if (!contextObject.Singleton)
                {
                    //Create instance every request
                    this.CreateNewInstance(factory, controllerName, out controller);
                    setInstanceProperty();
                }
                else
                {
                    //Singleton
                    if (contextObject.Object == null)
                    {
                        this.CreateNewInstance(factory, controllerName, out controller);
                        setInstanceProperty();
                        contextObject.Object = controller;
                    }
                    else
                    {
                        controller = contextObject.Object as IController;
                    }
                }
                 */
            }
            if (controller == null)
            {
                throw new MvcException("The controller created is null");
            }
            try
            {
                controller.Execute(RequestContext);
            }
            finally
            {
                factory.ReleaseController(controller);
            }
        }
    }
}
